#include <Memory/Paging.h>
#include <Utility/CLib.h>
#include <IntExcept/Debug.h>

/*
@brief 回收页面和分配的页框（若有）
@param `lpVirtualPage` 虚拟页面地址，忽略末尾 12 位
@param `dwCount` 连续释放的页面数量
@return 状态码
*/
DWORD FreePage(LPVOID lpVirtualPage, DWORD dwCount)
{
    DWORD dwPDE = RESOLVE_PDE_INDEX((DWORD_PTR)lpVirtualPage);
    DWORD dwPTE = RESOLVE_PTE_INDEX((DWORD_PTR)lpVirtualPage);
    PageTableEntry* lpPTE = (LPVOID)GENERATE_VIRTUAL_ADDRESS(1023, dwPDE, dwPTE); /* 页面对应的 PTE 在逻辑上连续存放 */
    for (DWORD i = 0; i < dwCount; i++)
    {
        if ((*lpPTE & PTE_PRESENT) != 0) /* 存在物理页框 */
        {
            DWORD dwStatus = FreeFrame(*lpPTE & 0xFFFFF000); /* 释放物理页框 */
            KERNEL_ASSERT(dwStatus == FRAME_FREE_SUCCESS, "Fails to free virtual page.\r\n")
        }
        *lpPTE = 0; /* 页表项清空 */
    }
    return PAGE_FREE_SUCCESS;
}